package com.ddch.tinkerlib.utils;

import java.lang.reflect.Field;

/**
 * created by 韦敏敏
 * on 2019/12/9
 */
public class ReflectUtils {
    /**
     *  通过反射获取某对象，并设置私有可访问
     * @param obj  该属性所属类的对象
     * @param clazz 该对象所属类
     * @param field  属性名
     * @return
     */
    public static Object getField(Object obj, Class<?> clazz, String field) throws NoSuchFieldException, IllegalAccessException {
        Field localField = clazz.getDeclaredField(field);
        localField.setAccessible(true);
        return localField.get(obj);
    }

    /**
     * 通过反射获取BaseDexClassLoader对象中的PathList对象
     * @param baseDexClassLoader  BaseDexClassLoader对象
     * @return  PathList对象
     * @throws ClassNotFoundException
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public static Object getPathList(Object baseDexClassLoader) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
        return getField(baseDexClassLoader, Class.forName("dalvik.system.BaseDexClassLoader"), "pathList");
    }

    /**
     *  给某属性赋值，并设置私有属性可访问
     * @param obj  该属性所属类的对象
     * @param clazz  该对象所属的类
     * @param value  值
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public static void setField(Object obj, Class<?> clazz, Object value) throws NoSuchFieldException, IllegalAccessException {
        Field localField = clazz.getDeclaredField("dexElements");
        localField.setAccessible(true);
        localField.set(obj, value);

    }
    /**
     * 通过反射获取BaseDexClassLoader对象中的PathList对象，再获取dexElements对象
     * @param paramObj  PathList对象
     * @return dexElements对象
     * @throws NoSuchFieldException
     * @throws IllegalAccessException
     */
    public static Object getDexElements(Object paramObj) throws NoSuchFieldException, IllegalAccessException {
        return getField(paramObj, paramObj.getClass(), "dexElements");
    }

}
